<?php

namespace app\api\service\order;

use app\common\library\alipay\AliPay;
use app\common\library\easywechat\AppOpen;
use app\common\library\easywechat\AppWx;
use app\common\library\easywechat\AppMp;
use app\common\library\easywechat\WxPay;
use app\common\enum\order\OrderTypeEnum;
use app\common\enum\order\OrderPayTypeEnum;
use app\common\library\helper;
use app\common\model\order\OrderTrade as OrderTradeModel;
use app\common\service\order\OrderService;
use Carbon\Carbon;

class LakalaPaymentService
{
    private $appid;
    private $mchSerialNo;
    private $mercId;
    private $termNo;
    private $merchantPrivateKeyPath;
    private $lklCertificatePath;
    private $subject;
    private $schema = 'LKLAPI-SHA256withRSA';
    private $version = '3.0';
    private $exterOrderSource = 'OS10000071';
    private $notify_url = '';

    public function __construct()
    {
        $config = config('lakala');
//        $config = config('wechat.payment.lakala_test');

        $this->url = $config['url']; // 接入url
        $this->appid = $config['appid'];  //接入方唯一编号
        $this->mchSerialNo = $config['mchSerialNo'];  //证书序列号
        $this->mercId = $config['mercId'];     //商户号
        $this->termNo = $config['termNo'];    //终端号
        $this->timeStamp = time();        //时间戳
        $this->nonceStr = 123456789012;        //随机12位字符串
        $this->SM4Key = 'UWBPi0shIG0N4RsejkR+Sg=='; //国密4
        $this->Algorism = 'LKLAPI-SHA256withRSA';     //头部加密标识
        $this->version = '3.0';
        $this->sub_appid = $config['sub_appid'];
        $this->cert_path = $config['cert_path'];
        $this->notify_url = $config['notify_url'];
    }

    public function lakalaCashierDesk($openid, $out_trade_no, $total_fee)
    {
//        $url = $this->url . '/api/v3/labs/trans/preorder';
        $url = 'https://test.wsmsd.cn/sit/api/v3/ccss/counter/order/create';
        $total_fee = bcmul($total_fee, 100, 2);
        $total_fee = intval($total_fee);
        $timestr = date('YmdHis', strtotime('+1 day'));
        $data = [
            'req_time' => date('Ymdhms'),
            'version' => $this->version,
            'req_data' => [
                'merchant_no' => $this->mercId,
                'out_order_no' => $out_trade_no,
                'channel_id' => '',
                'vpos_id' => $this->termNo,
                'total_amount' => $total_fee,  //单位分，整数型字符
                'notify_url' => $this->notify_url,  //余额支付回调
                'support_cancel' => 0,
                'support_refund' => 1,
                'support_repeat_pay' => 1,
                'order_info' => '订单支付',
                'order_efficient_time' => $timestr,
                "busi_type_param" => "[{\"busi_type\":\"UPCARD\",\"params\":{\"crd_flg\":\"CRDFLG_D|CRDFLG_C|CRDFLG_OTH\"}},{\"busi_type\":\"SCPAY\",\"params\":{\"pay_mode\":\"WECHAT\",\"crd_flg\":\"CRDFLG_D\"}}]",
                "counter_param" => "{\"pay_mode\":\"ALIPAY\"}",
                "out_user_id" => "",
                "order_info" => "自动化测试",
                "extend_info" => "自动化测试",
                "callback_url" => ""
            ],
        ];

        $body = json_encode($data, JSON_UNESCAPED_UNICODE);
        $Authorization = $this->getSign($body);
        $ret_data = $this->post_curl($url, $data, $Authorization);
        if ($ret_data['code'] != 'BBS00000') {
            throw new ErrorException(Error::ERROR_LAKALA_FAIL, $ret_data['msg']);
        }
        return $ret_data['resp_data']['acc_resp_fields'];
    }

    public function payOrder($openid, $out_trade_no, $total_fee)
    {
        $url = $this->url . '/api/v3/labs/trans/preorder';
        $total_fee = bcmul($total_fee, 100, 2);
        $total_fee = intval($total_fee);
        $data = [
            'req_time' => date('Ymdhms'),
            'version' => $this->version,
            'req_data' => [
                'merchant_no' => $this->mercId,
                'term_no' => $this->termNo,
                'out_trade_no' => $out_trade_no,
                'account_type' => 'WECHAT',
                'trans_type' => 71,  //接入方式  71:微信小程序支付
                'total_amount' => $total_fee,  //单位分，整数型字符
                'location_info' => array('request_ip' => $_SERVER['REMOTE_ADDR']),
                'notify_url' => $this->notify_url,  //余额支付回调
                'acc_busi_fields' => [
                    'timeout_express' => 15, //订单过期时间 分钟
                    'sub_appid' => $this->sub_appid,
                    'user_id' => $openid,
                ],
            ],
        ];

        $body = json_encode($data, JSON_UNESCAPED_UNICODE);
        $Authorization = $this->getSign($body);
        $ret_data = $this->post_curl($url, $data, $Authorization);
        if ($ret_data['code'] != 'BBS00000') {
            throw new ErrorException(Error::ERROR_LAKALA_FAIL, $ret_data['msg']);
        }
        return $ret_data['resp_data']['acc_resp_fields'];

    }

    public function refund($origin_out_trade_no, $refund_amount)
    {
        //退款
        $url = $this->url . '/api/v3/labs/relation/refund';

        $refund_out_trade_no = randomString(10);

        $refund_amount = bcmul($refund_amount, 100, 2);
        $refund_amount = intval($refund_amount);

        $data = [
            'req_time' => date('Ymdhms'),
            'version' => $this->version,
            'req_data' => [
                'merchant_no' => $this->mercId,
                'term_no' => $this->termNo,
                'out_trade_no' => $refund_out_trade_no,  //创建新的订单号
                'refund_amount' => $refund_amount,
                'origin_out_trade_no' => $origin_out_trade_no, //原订单号
                'location_info' => array('request_ip' => $_SERVER['REMOTE_ADDR']),
            ],
        ];
        $body = json_encode($data, JSON_UNESCAPED_UNICODE);
        $Authorization = $this->getSign($body);
        $ret_data = $this->post_curl($url, $data, $Authorization);
        if ($ret_data['code'] != 'BBS00000') {
            throw new ErrorException(Error::ERROR_LAKALA_FAIL, $ret_data['msg']);
        }
        return true;
    }

    public function post_curl($url, $data, $Authorization)
    {
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => array(
                'Authorization: ' . $Authorization,
                'Accept: application/json',
                'Content-Type: application/json',
            ),
        ));
        $response = curl_exec($curl);
        curl_close($curl);
        return json_decode($response, 1);
    }

    //生成 sha256WithRSA 签名
    public function getSign($body)
    {
        $message = $this->appid . "\n" . $this->mchSerialNo . "\n" . $this->timeStamp . "\n" . $this->nonceStr . "\n" . $body . "\n";
        $privateKey = file_get_contents($this->cert_path);
        $key = openssl_get_privatekey($privateKey);
//      print_r($message);die;
        openssl_sign($message, $signature, $key, OPENSSL_ALGO_SHA256);
        openssl_free_key($key);
        return $this->schema . " appid=\"" . $this->appid . "\"," . "serial_no=\"" . $this->mchSerialNo . "\"," . "timestamp=\"" . $this->timeStamp . "\"," . "nonce_str=\"" . $this->nonceStr . "\"," . "signature=\"" . base64_encode($signature) . "\"";
    }
}
